#ifndef BWT_H
#define	BWT_H
#include "../../include/hzstream.h"
#include <stdint.h>

namespace bwt{
class BWTencoder{
public:
    BWTencoder(int32_t buf_size);
    ~BWTencoder();
    void encode(hzstream* hz);
    int32_t encode(uint8_t* in_buf, uint8_t* out_buf,int32_t buf_size);
private:
    void _sortSuffixes(uint8_t* in_buf, int32_t* A,int32_t buf_size);
    void _radixSort(uint8_t* in_buf,int32_t buf_size,int32_t* A,int32_t start,int32_t end);

    int32_t _buf_size;
    int32_t* _A;
    

    /**
     Struct for most significant digit radix sort impl.
     */
    struct classForRadix {
        int32_t dist;
        int32_t start;
        int32_t end;
        classForRadix(int32_t d,int32_t s,int32_t e): dist(d),start(s),end(e) {}
        classForRadix(){}
    };
};

class BWTdecoder {
public:
    BWTdecoder(int32_t buf_size);
    ~BWTdecoder();

    void decode(hzstream* hz);
    void decode(uint8_t* in_buf, int32_t index, uint8_t* out_buf, int32_t buf_size);
private:
    void _makeLookupInVP(uint8_t *in_buf,int32_t* lookup,int32_t buf_size);

    int32_t* _VT;
    int32_t _buf_size;
};

}
#endif	/* BWT_H */

